package Redis缓存数据.GEO;

import com.ruoyi.charge.common.GlobalConstant;
import com.ruoyi.charge.domain.ChargingStation;
import com.ruoyi.charge.mapper.ChargingStationMapper;
import com.ruoyi.charge.service.IChargingStationService;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 充电站Service业务层处理
 *
 * @author ruoyi
 * @date 2022-11-10
 */
@Service
public class ChargingStationServiceImpl implements IChargingStationService
{
    @Autowired
    private ChargingStationMapper chargingStationMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public List<NearbyChargingStation> selectNearbyChargingStation(double longitude, double latitude, double radius) {
        ArrayList<NearbyChargingStation> list = new ArrayList<>();
        //1,创建point表示用户位置
        Point userPosition = new Point(longitude, latitude);
        //public enum Metrics implements Metric {
        //    KILOMETERS(6378.137, "km"),

        Distance distance = new Distance(radius, Metrics.KILOMETERS);
        //public Distance(double value, Metric metric)

        Circle circle = new Circle(userPosition, distance);
        // public Circle(Point center, Distance radius)
        //public static GeoRadiusCommandArgs newGeoRadiusArgs()
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        //设置返回距离
        geoRadiusCommandArgs.includeDistance();
        //设置返回坐标
        geoRadiusCommandArgs.includeCoordinates();

        //GeoResults<GeoLocation<M>> radius(Circle within, GeoRadiusCommandArgs args);
        BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps(GlobalConstant.STATION_GEO_ZSET);
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = boundGeoOperations.radius(circle, geoRadiusCommandArgs);
        System.out.println(geoResults);
        //public class GeoResults<T> implements Iterable<GeoResult<T>>, Serializable
        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(GlobalConstant.STATION_DETAIL_HASH);
        //遍历附近充电站

        Iterator<GeoResult<RedisGeoCommands.GeoLocation<String>>> iterator = geoResults.iterator();
        while (iterator.hasNext()) {
            //取充电站
            GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult = iterator.next();
            //取充电站编号
            String stationId = geoResult.getContent().getName();
            //从stationDetailHash取充电站详情
            ChargingStation chargingStation = (ChargingStation) boundHashOperations.get(stationId);
            //取距离
            double userDistance = geoResult.getDistance().getValue();
            //创建NearbyChargingStation
            NearbyChargingStation nearbyChargingStation = new NearbyChargingStation();
            BeanUtils.copyProperties(chargingStation,nearbyChargingStation);
            nearbyChargingStation.setDistance(userDistance);

            list.add(nearbyChargingStation);
        }
        return list;
    }

    /**
     * 查询充电站
     *
     * @param id 充电站主键
     * @return 充电站
     */
    @Override
    public ChargingStation selectChargingStationById(Integer id)
    {
        //return chargingStationMapper.selectChargingStationById(id);
        ChargingStation chargingStation=null;
        //先从redis中查
        BoundHashOperations boundHashOperations = redisTemplate.boundHashOps(GlobalConstant.STATION_DETAIL_HASH);
        chargingStation  = (ChargingStation) boundHashOperations.get(id.toString());
        //判断是否为空
        if(ObjectUtils.isEmpty(chargingStation)) {
            //为空，redis中没有，再去数据库中查
            chargingStation=chargingStationMapper.selectChargingStationById(id);
        }
        return  chargingStation;
    }

    /**
     * 查询充电站列表
     *
     * @param chargingStation 充电站
     * @return 充电站
     */
    @Override
    public List<ChargingStation> selectChargingStationList(ChargingStation chargingStation)
    {
        return chargingStationMapper.selectChargingStationList(chargingStation);
    }

    /**
     * 新增充电站
     *
     * @param chargingStation 充电站
     * @return 结果
     */
    @Override
    public int insertChargingStation(ChargingStation chargingStation)
    {
        return chargingStationMapper.insertChargingStation(chargingStation);
    }

    /**
     * 修改充电站
     *
     * @param chargingStation 充电站
     * @return 结果
     */
    @Override
    public int updateChargingStation(ChargingStation chargingStation)
    {
        return chargingStationMapper.updateChargingStation(chargingStation);
    }

    /**
     * 批量删除充电站
     *
     * @param ids 需要删除的充电站主键
     * @return 结果
     */
    @Override
    public int deleteChargingStationByIds(Integer[] ids)
    {
        return chargingStationMapper.deleteChargingStationByIds(ids);
    }

    /**
     * 删除充电站信息
     *
     * @param id 充电站主键
     * @return 结果
     */
    @Override
    public int deleteChargingStationById(Integer id)
    {
        return chargingStationMapper.deleteChargingStationById(id);
    }
}
